package hyPeerDriveTests;

import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.Test;
import dbPhase.hypeerweb.*;

import phase4Specification.testing.DepositBroadcastVisitor;

public class KendraTests {

	/*
	 * Testing Broadcast
	 * 
	 * 
	 * Equivalence partitioning
	 * 
	 * Equivalence in where you broadcast from
	 * 1. Node.webid < 0
	 * 2. 0 <= Node.webid < HyPeerWeb.size
	 * 3. HyPeerWeb.size <= Node.webid
	 * 
	 */
	
	@Test
	public void test() {
		
		assertTrue(broadcast(0,32));
		assertTrue(broadcast(16,32));
		assertTrue(broadcast(31,32));
		assertTrue(broadcastBadNode(-1,32));
		assertTrue(broadcastBadNode(-16,32));
		assertTrue(broadcastBadNode(32,32));
		assertTrue(broadcastBadNode(48,32));
	}

	public void createHyPeerWebWithSize(HyPeerWeb hp, int size) {
		hp.clear();
		Node n0 = new Node(0);
		hp.addToHyPeerWeb(n0, null);
		for(int i = 1; i < size; i++) {
			hp.addToHyPeerWeb(new Node(0), n0);
		}
	}
	
	public boolean allNodesHaveMessage(HyPeerWeb hp) {
		Iterator<Node> nodes = hp.iterator();
		while(nodes.hasNext()) {
			Node n = nodes.next();
			if(!n.getContents().get(DepositBroadcastVisitor.DEPOSIT_KEY).equals("Hello!")) {
				return false;
			}
		}
		return true;
	}
	
	public boolean broadcast(int startNode, int size) {
		HyPeerWeb hp = HyPeerWeb.getSingleton();
		createHyPeerWebWithSize(hp, size);
		DepositBroadcastVisitor db = new DepositBroadcastVisitor();
		Parameters p = BroadcastVisitor.createInitialParameters();
		p.set(DepositBroadcastVisitor.DEPOSIT_KEY, "Hello!");
		
		Node n = hp.getNode(startNode);
		db.visit(n, p);
		
		return allNodesHaveMessage(hp);
	}
	
	public boolean noNodesHaveMessage(HyPeerWeb hp) {
		Iterator<Node> nodes = hp.iterator();
		while(nodes.hasNext()) {
			Node n = nodes.next();
			if(n.getContents().containsKey(DepositBroadcastVisitor.DEPOSIT_KEY)) {
				return false;
			}
		}
		return true;
	}
	
	public boolean broadcastBadNode(int startNode, int size) {
		HyPeerWeb hp = HyPeerWeb.getSingleton();
		createHyPeerWebWithSize(hp, size);
		DepositBroadcastVisitor db = new DepositBroadcastVisitor();
		Parameters p = BroadcastVisitor.createInitialParameters();
		p.set(DepositBroadcastVisitor.DEPOSIT_KEY, "Hello!");
		
		Node n = new Node(startNode);
		db.visit(n, p);
		
		return noNodesHaveMessage(hp);
	}
}
